package com.em.frame.shiro;

import com.em.common.model.SysPermission;
import com.em.common.model.SysRole;
import com.em.common.model.SysUser;
import com.em.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;

import java.util.List;

/**
 * Created by zlx on 2017/12/12 0012.
 */
public class ShiroDbRealm extends AuthorizingRealm {


    /**
     * 身份证认证
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("##### 身份证认证 #####");
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) authenticationToken;
        String username = usernamePasswordToken.getUsername();
        SysUser user = UserService.me.findUserByUsername(username);
        if (user != null) {
            //检测密码是否正确交给凭证匹配
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user.getLoginAccount(), user.getLoginPass(), getName());
            ShiroCache.setLoginUser(user);
            return info;
        } else {
            return null;
        }
    }


    /**
     * 权限认证
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("##### 权限认证 #####");
        String loginName = (String) principalCollection.fromRealm(getName()).iterator().next();
        SysUser user = UserService.me.findUserByUsername(loginName);
        if (user != null) {
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            authRole(user.getUserId(),info);
            return info;
        } else {
            return null;
        }
    }

    /**
     * 角色授权
     * @param id
     * @param info
     */
    protected void authRole(long id, SimpleAuthorizationInfo info) {
        List<SysRole> list = UserService.me.findUserRoles(id);
        ShiroCache.setAttribute(ShiroCache.LOGIN_ROLE,list);
        for (SysRole role : list) {
            info.addRole(role.getRoleKey());
            authUrl(role.getRoleKey(), info);
        }
    }

    /**
     * 资源授权
     * @param roleKey
     * @param info
     */
    protected void authUrl(String roleKey, SimpleAuthorizationInfo info) {
        List<SysPermission> list = UserService.me.findUserPermission(roleKey);
        ShiroCache.setAttribute(ShiroCache.LOGIN_PERMISSION,list);
        for (SysPermission resource : list) {
            info.addStringPermission(resource.getDataUrl());
        }
    }


    public void clearCacheAuth(Object principal) {
        SimplePrincipalCollection info = new SimplePrincipalCollection(principal, getName());
        clearCachedAuthenticationInfo(info);
    }

    public void clearAllCacheAuth() {
        Cache<Object, AuthenticationInfo> cache = getAuthenticationCache();
        if (null != cache) {
            for (Object key : cache.keys()) {
                cache.remove(key);
            }
        }
    }
}
